package com.zzh.rxandroid.schedulers;


import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.zzh.rxandroid.plugins.RxAndroidPlugins;

import io.reactivex.rxjava3.core.Scheduler;

/**
 * Created by zzh on 2025/7/1.
 *
 * @date: 2025/7/1 10:52
 * @email: zzh_hz@126.com
 * @author: zzh
 * @description: com.zzh.rxandroid.schedulers
 */
public final class AndroidSchedulers {
    private static final class MainHolder {
        static final Scheduler DEFAULT = internalFrom(Looper.getMainLooper(), true);
    }

    private static final Scheduler MAIN_THREAD =
            RxAndroidPlugins.initMainThreadScheduler(() -> MainHolder.DEFAULT);

    /**
     * A {@link Scheduler} which executes actions on the Android main thread.
     * <p>
     * The returned scheduler will post asynchronous messages to the looper by default.
     *
     * @see #from(Looper, boolean)
     */
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

    /**
     * A {@link Scheduler} which executes actions on {@code looper}.
     * <p>
     * The returned scheduler will post asynchronous messages to the looper by default.
     *
     * @see #from(Looper, boolean)
     */
    public static Scheduler from(Looper looper) {
        return from(looper, true);
    }

    /**
     * A {@link Scheduler} which executes actions on {@code looper}.
     *
     * @param async if true, the scheduler will use async messaging on API >= 16 to avoid VSYNC
     *              locking. On API < 16 this value is ignored.
     * @see Message#setAsynchronous(boolean)
     */
    public static Scheduler from(Looper looper, boolean async) {
        if (looper == null) throw new NullPointerException("looper == null");
        return internalFrom(looper, async);
    }

    @SuppressLint("NewApi") // Checking for an @hide API.
    private static Scheduler internalFrom(Looper looper, boolean async) {
        // Below code exists in androidx-core as well, but is left here rather than include an
        // entire extra dependency.
        // https://developer.android.com/reference/kotlin/androidx/core/os/MessageCompat?hl=en#setAsynchronous(android.os.Message,%20kotlin.Boolean)
        return new HandlerScheduler(new Handler(looper), async);
    }

    private AndroidSchedulers() {
        throw new AssertionError("No instances.");
    }
}
